import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:facebook_app_events/facebook_app_events.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:medito/constants/http/http_constants.dart';
import 'package:medito/constants/strings/analytics_event_constants.dart';
import 'package:medito/constants/strings/shared_preference_constants.dart';
import 'package:medito/utils/logger.dart';

class MetaSdkService {
  MetaSdkService._();

  static final MetaSdkService instance = MetaSdkService._();
  bool _initialised = false;
  final FacebookAppEvents _events = FacebookAppEvents();
  static const MethodChannel _channel =
      MethodChannel('com.medito.app/facebook');

  Future<void> init() async {
    if (_initialised) {
      return;
    }

    AppLogger.d('META', 'Init Facebook App Events (appId=$facebookAppId)');

    // facebook_app_events initialises using platform configs.
    // If consent gating is required, handle it before enabling tracking.

    _initialised = true;
  }

  /// Update Facebook SDK advertiser tracking enabled flag based on ATT status
  /// This is required for iOS 14+ SKAdNetwork attribution
  /// Call this after ATT permission has been requested
  Future<void> updateTrackingStatus() async {
    if (!Platform.isIOS) {
      return;
    }

    try {
      final status = await AppTrackingTransparency.trackingAuthorizationStatus;
      final isAuthorized = status == TrackingStatus.authorized;

      // Set advertiser tracking enabled via platform channel
      // This tells Facebook SDK whether it can use IDFA for attribution
      await _channel.invokeMethod('setAdvertiserTrackingEnabled', isAuthorized);

      if (kDebugMode) {
        AppLogger.d('META',
            'Set advertiser tracking enabled: $isAuthorized (ATT status: $status)');
      }
    } catch (e) {
      if (kDebugMode) {
        AppLogger.w('META', 'Failed to set advertiser tracking enabled: $e');
      }
    }
  }

  Future<void> setUserId(String? userId) async {
    try {
      if (userId == null || userId.isEmpty) {
        await _events.clearUserID();
      } else {
        await _events.setUserID(userId);
      }
      AppLogger.d('META', 'Set user ID for FB events: $userId');
    } catch (e) {
      if (kDebugMode) {
        AppLogger.w('META', 'Failed to set FB user ID: $e');
      }
    }
  }

  Future<void> logEvent(String name, Map<String, Object?> params) async {
    try {
      // Check if Meta Analytics is enabled by user preference
      final prefs = await SharedPreferences.getInstance();
      final isEnabled =
          prefs.getBool(SharedPreferenceConstants.analyticsMetaEnabled) ?? true;

      if (!isEnabled) {
        if (kDebugMode) {
          AppLogger.d('META',
              'Analytics disabled by user preference, skipping event: $name');
        }
        return;
      }

      await _events.logEvent(name: name, parameters: params);
      if (kDebugMode) {
        AppLogger.d('META', 'Logged FB event: $name');
      }
    } catch (e) {
      if (kDebugMode) {
        AppLogger.w('META', 'Failed to log FB event $name: $e');
      }
    }
  }

  Future<void> logAppFirstOpenOnce() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      const key = 'meta_app_first_open_logged';
      if (prefs.getBool(key) == true) return;

      // Get stored UTM parameters to include in first open event
      final utmParams = await _getStoredUtmParameters();

      await logEvent(AnalyticsEventConstants.appFirstOpen, utmParams);
      await prefs.setBool(key, true);
    } catch (e, stack) {
      AppLogger.e('META', 'Failed to log app_first_open', e, stack);
    }
  }

  Future<Map<String, Object?>> _getStoredUtmParameters() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      final utmParams = <String, Object?>{};

      final utmParamMap = {
        SharedPreferenceConstants.utmSource: 'utm_source',
        SharedPreferenceConstants.utmMedium: 'utm_medium',
        SharedPreferenceConstants.utmCampaign: 'utm_campaign',
        SharedPreferenceConstants.utmTerm: 'utm_term',
        SharedPreferenceConstants.utmContent: 'utm_content',
      };

      for (final entry in utmParamMap.entries) {
        final value = prefs.getString(entry.key);
        if (value != null && value.isNotEmpty) {
          utmParams[entry.value] = value;
        }
      }

      return utmParams;
    } catch (e) {
      if (kDebugMode) {
        AppLogger.w('META', 'Error getting stored UTM parameters: $e');
      }
      return {};
    }
  }

  Future<void> logDonationEvents({
    required int revenueCents,
    required String currency,
    required String frequency,
  }) async {
    final props = {
      AnalyticsEventConstants.paramRevenue: revenueCents,
      AnalyticsEventConstants.paramCurrency: currency,
    };

    await logEvent(AnalyticsEventConstants.paywallDonation, props);

    var freqEvent = AnalyticsEventConstants.oneTimeDonation;
    if (frequency == 'monthly') {
      freqEvent = AnalyticsEventConstants.monthlyDonation;
    }
    if (frequency == 'yearly') {
      freqEvent = AnalyticsEventConstants.yearlyDonation;
    }

    await logEvent(freqEvent, props);
  }
}
